import maya.cmds as mc
import maya.mel as mel

class LZ_createCurrentShape():
    def createCorrectBlendTarget(self,sculptMesh,cache):

        shaopeMesh=mc.pickWalk(sculptMesh,d='down')
        node=mc.createNode('sculptToBlendTarget',n=str(sculptMesh)+'_correctBlendShape')
        mc.connectAttr(str(cache)+'.poseSpaceRow0',str(node)+'.poseSpaceRow0')
        mc.connectAttr(str(cache)+'.poseSpaceRow1',str(node)+'.poseSpaceRow1')
        mc.connectAttr(str(cache)+'.poseSpaceRow2',str(node)+'.poseSpaceRow2')
        mc.connectAttr(str(cache)+'.bindPoint',str(node)+'.bindPoint')
        mc.connectAttr(str(cache)+'.posePoint',str(node)+'.posePoint')
        
        mc.connectAttr(str(shaopeMesh[0])+'.outMesh',str(node)+'.sculptMesh')
        
        mc.setAttr(str(node)+'.poseFile',cache,type='string')
        
        target=mc.polyCube(ch=False,n=str(sculptMesh)+'_Tgt')
        mc.move(-27,0,0,target[0],r=True,ws=True)
        TgtshaopeMesh=mc.pickWalk(target[0],d='down')
        mc.connectAttr(str(node)+'.outMesh',str(TgtshaopeMesh[0])+'.inMesh')
        
        return target[0]
    
    def setupCorrentShape(self):
        selobj=mc.ls(sl=True)
        if len(selobj)<1:
            print('must select a mesh\n')
        else:
            
            scupltMesh=self.duplicateMeshToScupltMesh(selobj[0])
            print(scupltMesh)
            refMesh=self.duplicateSkinnedMeshAtBindPos(selobj[0])

            if refMesh=='nil':
                pass
            else:
                blend=self.CB_getBlendshapeNode(selobj[0])
                if blend =='':
                    blend=mc.blendShape(selobj[0],foc=True)[0]
                
                self.CB_addTargetToBlend(refMesh[0],selobj[0],blend)

                refMeshShape=self.CB_getShapeFullPath(refMesh)[0]
                poseMeshShape=self.CB_getShapeFullPath(selobj[0])[0]

                cache=mel.eval('calculatePoseSpace -pa ' + poseMeshShape +' -bt '+ refMeshShape+' -cc')
                self.CB_removeTargetFromBlend(refMesh[0],selobj[0],blend)
                
                mc.delete(refMesh)
                
                if cache=='':
                    pass
                else:
                    target=self.createCorrectBlendTarget(scupltMesh[0],cache)
                    
                    mc.select(str(scupltMesh[0])+ ".vtx[0]",r=True)
                    #mc.move( -0.177854,-0.681621,0.0358554 ,str(target) + '.vtx[0]')
                    #mc.move(0.177854,0.681621,-0.0358554,str(target) + '.vtx[0]')
                    mc.select(cl=True)

                
                
                
        
    def duplicateMeshToScupltMesh(self,mesh):
        refname=mc.duplicate(mesh,n=str(mesh)+'_CBsuplt_Mesh')
        for attr in ['.tx','.ty','.tz','.rx','.ry','.rz','.sx','.sy','.sz']:
            mc.setAttr(str(refname[0])+attr,lock=False)
        mc.move(37,0,0,refname,ws=True)
        return refname
        
    def duplicateMeshAsTargetMesh(self,mesh):
        refname=mc.duplicate(mesh,n=str(mesn)+'_CBsupltTgt')
        mc.setAttr(str(refname)+'.tx',lock=False)
        mc.move(-37,0,0,refname)
        return refname
    
    def  duplicateSkinnedMeshAtBindPos(self,mesh):
        skinnode=self.CB_findSkinnodeAtMesh(mesh)
        
        if skinnode=='':
            print('found no skin cluster!')
            return 'nil'
        else:
            mc.setAttr(str(skinnode)+'.envelope',0)
            refname=mc.duplicate(mesh,n=str(mesh)+'_CBSRef')
            
            mc.setAttr(str(skinnode)+'.envelope',1)
            
            mc.setAttr(str(refname[0])+'.tx',lock=False)
            mc.move(-37,0,0,refname)
            
            return refname
    
    def CB_getBlendshapeNode(self,mesh):
        blendNode=''
        for leave in range(6):
            
        
            nodeHistory=mc.listHistory(mesh,lv=leave+1)

            for i in nodeHistory:

                if mc.nodeType(i)=='blendShape':
                    blendNode=i
            if blendNode!='':
                break
        return blendNode
    
    
    def CB_findSkinnodeAtMesh(self,mesh):
        skinnode=mel.eval('findRelatedSkinCluster '+ mesh)
        return skinnode
        
    def CB_addTargetToBlend(self,ref,mesh,blend):
        existingNumTargets=mc.blendShape(blend,q=True,wc=True)
        lastIndex=self.CB_findLastIndex(blend)
        
        mc.blendShape(blend,e=True,tc=True,t=[mesh,lastIndex,ref,1])
        mc.setAttr(str(blend)+'.'+str(ref),1)
    
    def CB_getFullPath(self,obj):
        full=mc.ls(obj,l=True)
        return full
        
    def CB_getShapeFullPath(self,obj):
        shape=mc.pickWalk(obj,d='down')
        return self.CB_getFullPath(shape)
    
    
    
    '''
    getWeightIndex(string,string)
    get the index of the weight input    get (int)
    
    ''' 
    def CB_getWeightIndex(self,blendShapeNode,target):
        aliases=mc.aliasAttr(blendShapeNode,q=True)

        for i in range(len(aliases)):
            if target==aliases[i]:
                index=(aliases[i+1].split('[')[1]).split(']')[0]
                
                index=int(index)+1
                break
            else:
                index='something mistake has Occurred'

        return index
        
    def CB_findLastIndex(self,blendShapeNode):
        aliases=mc.aliasAttr(blendShapeNode,q=True)
        index=1
        if aliases==None:
            index= 0
        else:
            for i in range(len(aliases)/2):
                currentIndex=int((aliases[i*2+1].split('[')[1]).split(']')[0])+1
                if currentIndex>index:
                    index=currentIndex
        return(index)
        
    def CB_removeTargetFromBlend(self,target,mesh,blend):
        targetIndex=self.CB_getWeightIndex(blend,target)

        mc.blendShape(blend,e=True,rm=True,t=[mesh,targetIndex,target,1])
    
    